One-Hot Encoding

X=df[['color','size','price']].values
color_le=LabelEncoder()
X[:,0]=color_le.fit_transform(X[:,0])
X

array([[1, 'M', 10.1],

       [2, 'L', 13.5],

       [0, 'XL', 15.3]], dtype=object)

위와 같이 LabelEncoder()을 통해서 산편하게 문자열 레이블을 정수로 인코딩( “color"->int)
blue=0
green=1
red=2

LabelEncoder()는 입력 데이터로 1차원 배열을 기대함
OrdinalEncoder와 판다스 데이터프레임의 ColumnTransformer를 이용하면 여러개의 열을 한번에 정수로 변환할 수 있다.
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OrdinalEncoder
ord_enc=OrdinalEncoder(dtype=np.int)
col_trans=ColumnTransformer([('ord_enc', ord_enc, ['color'])])
X_trans=col_trans.fit_transform(df)
X_trans

array([[1],

       [2],

       [0]])

ColumnTransformer는 첫번째 변수로 트랜스포머(transformer)의 리스트를 받는다.
트랜스포머는 이름, 변환기, 변환할 열의 리스트로 이루어진 튜플이다.

OrdinalEncoder 클래스의 dtype 매개변수 기본값은 float64로 인코딩 된다.
다시 문자열로 되돌리기
col_trans.named_transformers_['ord_enc'].inverse_transform(X_trans)

array([['green'],

       ['red'],

       ['blue']], dtype=object)

위와 같이 color을 int형으로 바꾸고 데이터를 다루면 학습 알고리즘은 color을 크기 데이터로 인식한다.
이런 문제를 해결하기 위해서 one-hot encoding(원-핫 인코딩) 기법을 사용한다.
One-Hot encoding
순서 없는 특성에 들어 있는 고유한 값마다 새로운 더미(dummy) 특성을 만드는 것이다.
ex) 위의 color 특성을 세개의 새로운 특성인 blue, green, red로 변환한다.
이후 이진 값을 이용해서 특정 샘플의 color 특성을 나타낸다.
from sklearn.preprocessing import OneHotEncoder
X=df[['color', 'size', 'price']].values
color_ohe=OneHotEncoder()
color_ohe.fit_transform(X[:,0].reshape(-1,1)).toarray()

array([[0., 1., 0.],

       [0., 0., 1.],

       [1., 0., 0.]])

ColumnTransformer를 이용해서 특정 열만 변환할 수 있다.
from sklearn.compose import ColumnTransformer
X=df[['color', 'size', 'price']].values
c_transf=ColumnTransformer([
('onehot', OneHotEncoder(), [0]),
('nothing', 'passthrough', [1, 2])
])
c_transf.fit_transform(X)

array([[0.0, 1.0, 0.0, 'M', 10.1],

       [0.0, 0.0, 1.0, 'L', 13.5],

       [1.0, 0.0, 0.0, 'XL', 15.3]], dtype=object)

판다스의 get_dumies 메서드를 이용하여 원-핫 인코딩을 쉽게 할 수 있다.
pd.get_dummies(df[['price', 'color', 'size']])

   price  color_blue  color_green  color_red  size_L  size_M  size_XL

0   10.1           0            1          0       0       1        0

1   13.5           0            0          1       1       0        0

2   15.3           1            0          0       0       0        1

변환할려는 특성을 구체적으로 지정할 수도 있다.
pd.get_dummies(df[['price', 'color' ,'size']], columns=['size'])

   price  color  size_L  size_M  size_XL

0   10.1  green       0       1        0

1   13.5    red       1       0        0

2   15.3   blue       0       0        1

Multicollinearity(다중 공선성)
특성관의 상관관계가 높으면, 역행렬을 계산하기 어려워져 수치적으로 불안정해진다.
변수 간의 상관관계를 감소하려면, 원-핫 인코딩된 배열에서 특성 열 하나를 삭제한다.
(특성열을 하나 삭제해도 정보를 잃지 않는다. e.g. color_green=0, color_red=0 이면 color_green=1임을 알 수 있다.)
pd.get_dummies(df[['price', 'color', 'size']], drop_first=True)

   price  color_green  color_red  size_M  size_XL

0   10.1            1          0       1        0

1   13.5            0          1       0        0

2   15.3            0          0       0        1

중복된 열을 삭제
color_ohe=OneHotEncoder(categories='auto', drop='first')
c_transf=ColumnTransformer([
('onehot', color_ohe, [0]),
('nothing', 'passthrough', [1, 2])
])
c_transf.fit_transform(X)

array([[1.0, 0.0, 'M', 10.1],

       [0.0, 1.0, 'L', 13.5],

       [0.0, 0.0, 'XL', 15.3]], dtype=object)

순서있는 특성 인코딩
df=pd.DataFrame([['green', 'M', 10.1, 'class2'],
['red', 'L', 13.5, 'class1'],
['blue', 'XL', 15.3, 'class2']])
df.columns=['color', 'size', 'price', 'classlabel']
df['x > M']=df['size'].apply(lambda x:1 if x in{'L', 'XL'} else 0)
df['x > L']=df['size'].apply(lambda x:1 if x=='XL' else 0)
del df['size']
df

   color  price classlabel  x > M  x > L

0  green   10.1     class2      0      0

1    red   13.5     class1      1      0

2   blue   15.3     class2      1      1